home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / gnu / oleo_src.lha / src / string.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  7KB  |  341 lines

  1. /*    Copyright (C) 1990 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ctype.h>
  20. #include "funcdef.h"
  21. #define obstack_chunk_alloc ck_malloc
  22. #define obstack_chunk_free free
  23. #include "obstack.h"
  24. #include "sysdef.h"
  25.  
  26. #include "global.h"
  27. #include "cell.h"
  28. #include "eval.h"
  29. #include "errors.h"
  30.  
  31. struct value {
  32.     int    type;
  33.     union vals x;
  34. };
  35.  
  36. #define Float    x.c_d
  37. #define String    x.c_s
  38. #define Int    x.c_l
  39. #define Value    x.c_i
  40. #define Rng    x.c_r
  41.  
  42. #define ERROR(x)    \
  43.  {            \
  44.     p->Value=x;    \
  45.     p->type=TYP_ERR;\
  46.     return;        \
  47.  }
  48.     
  49.  
  50. extern struct obstack tmp_mem;
  51.  
  52. extern char *flt_to_str();
  53.  
  54. static void
  55. do_edit FUN2(int,numarg, struct value *,p)
  56. {
  57.     int mm;
  58.     int add_len;
  59.     int tmp_len;
  60.     char *ptr1,*ptr2,*retp;
  61.     int off1,off2;
  62.  
  63.     if(numarg<3)
  64.         ERROR(BAD_INPUT);
  65.     for(mm=3,add_len=0;mm<numarg;mm++)
  66.         add_len+=strlen((p+mm)->String);
  67.     tmp_len=strlen(p->String);
  68.     off1=(p+1)->Int;
  69.     off2=(p+2)->Int;
  70.     if(off1==0 || tmp_len < ((off1<0) ? -off1 : off1) ||
  71.        off2==0 || tmp_len < ((off2<0) ? -off2 : off2))
  72.         ERROR(OUT_OF_RANGE);
  73.     ptr1=p->String + (off1>0 ? off1-1 : tmp_len+off1);
  74.     ptr2=p->String + 1 + (off2>0 ? off2-1 : tmp_len+off2);
  75.     if(ptr1>ptr2)
  76.         ERROR(OUT_OF_RANGE);
  77.     retp=obstack_alloc(&tmp_mem,add_len+tmp_len-(ptr2-ptr1));
  78.     strncpy(retp,p->String,ptr1-p->String);
  79.     retp[ptr1-p->String]='\0';
  80.     for(mm=3;mm<numarg;mm++)
  81.         strcat(retp,(p+mm)->String);
  82.     strcat(retp,ptr2);
  83.     p->String=retp;
  84.     p->type=TYP_STR;
  85. }
  86.  
  87. static void
  88. do_repeat FUN1(struct value *,p)
  89. {
  90.     char *str = (p  )->String;
  91.     long num  = (p+1)->Int;
  92.  
  93.     char *ret;
  94.     char *strptr;
  95.     int len;
  96.  
  97.     if(num<0)
  98.         ERROR(OUT_OF_RANGE);
  99.     len=strlen(str);
  100.     ret=strptr=obstack_alloc(&tmp_mem,len*num+1);
  101.     while(num--) {
  102.         bcopy(str,strptr,len);
  103.         strptr+=len;
  104.     }
  105.     *strptr=0;
  106.     p->String=ret;
  107. }
  108.  
  109. static void
  110. do_len FUN1(struct value *,p)
  111. {
  112.     long ret;
  113.     char *ptr;
  114.  
  115.     for(ret=0,ptr=p->String;*ptr;ret++,ptr++)
  116.         ;
  117.     p->Int=ret;
  118.     p->type=TYP_INT;
  119. }
  120.  
  121. static void
  122. do_up_str FUN1(struct value *,p)
  123. {
  124.     char *s1,*s2;
  125.     char *strptr;
  126.  
  127.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  128.     for(s1=strptr,s2=p->String;*s2;s2++)
  129.         *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  130.     *s1=0;
  131.     p->String=strptr;
  132. }
  133.  
  134. static void
  135. do_dn_str FUN1(struct value *,p)
  136. {
  137.     char *s1,*s2;
  138.     char *strptr;
  139.  
  140.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  141.     for(s1=strptr,s2=p->String;*s2;s2++)
  142.         *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  143.     *s1=0;
  144.     p->String=strptr;
  145. }
  146.  
  147. static void
  148. do_cp_str FUN1(struct value *,p)
  149. {
  150.     char *strptr;
  151.     char *s1,*s2;
  152.     int wstart=1;
  153.  
  154.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  155.     for(s1=strptr,s2=p->String;*s2;s2++) {
  156.         if(!isalpha(*s2)) {
  157.             wstart=1;
  158.             *s1++= *s2;
  159.         } else if(wstart) {
  160.             *s1++ = (islower(*s2) ? toupper(*s2) : *s2);
  161.             wstart=0;
  162.         } else
  163.             *s1++ = (isupper(*s2) ? tolower(*s2) : *s2);
  164.     }
  165.     *s1=0;
  166.     p->String=strptr;
  167. }
  168.  
  169. static void
  170. do_trim_str FUN1(struct value *,p)
  171. {
  172.     char *s1,*s2;
  173.     int sstart=0;
  174.     char *strptr;
  175.  
  176.     strptr=obstack_alloc(&tmp_mem,strlen(p->String)+1);
  177.     for(s1=strptr,s2=p->String;*s2;s2++) {
  178.         if(!isascii(*s2) || !isprint(*s2))
  179.             continue;
  180.         if(*s2==' ') {
  181.                 if(sstart) {
  182.                 *s1++= *s2;
  183.                 sstart=0;
  184.             }
  185.         } else {
  186.             sstart=1;
  187.             *s1++= *s2;
  188.         }
  189.     }
  190.     *s1=0;
  191.     p->String=strptr;
  192. }
  193.  
  194. static void
  195. do_concat FUN2(int, numarg, struct value *,p)
  196. {
  197.     int cur_string;
  198.     char *s;
  199.     char buf[40];
  200.     CELLREF crow,ccol;
  201.     CELL *cell_ptr;
  202.  
  203.     for(cur_string=0;cur_string<numarg;cur_string++) {
  204.         switch(p[cur_string].type) {
  205.         case 0:
  206.             continue;
  207.         case TYP_RNG:
  208.             for(crow=p[cur_string].Rng.lr;crow<=p[cur_string].Rng.hr;crow++)
  209.                 for(ccol=p[cur_string].Rng.lc;ccol<=p[cur_string].Rng.hc;ccol++) {
  210.                     if(!(cell_ptr=find_cell(crow,ccol)))
  211.                         continue;
  212.                     switch(GET_TYP(cell_ptr)) {
  213.                     case 0:
  214.                         break;
  215.                     case TYP_STR:
  216.                         (void)obstack_grow(&tmp_mem,cell_ptr->cell_str,strlen(cell_ptr->cell_str));
  217.                         break;
  218.                     case TYP_INT:
  219.                         sprintf(buf,"%ld",cell_ptr->cell_int);
  220.                         (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  221.                         break;
  222.                     case TYP_FLT:
  223.                         s=flt_to_str(cell_ptr->cell_flt);
  224.                         (void)obstack_grow(&tmp_mem,s,strlen(s));
  225.                         break;
  226.                     default:
  227.                         (void)obstack_finish(&tmp_mem);
  228.                         ERROR(NON_STRING);
  229.                     }
  230.             }
  231.             break;
  232.         case TYP_STR:
  233.             s=p[cur_string].String;
  234.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  235.             break;
  236.         case TYP_INT:
  237.             sprintf(buf,"%ld",p[cur_string].Int);
  238.             (void)obstack_grow(&tmp_mem,buf,strlen(buf));
  239.             break;
  240.         case TYP_FLT:
  241.             s=flt_to_str(p[cur_string].Float);
  242.             (void)obstack_grow(&tmp_mem,s,strlen(s));
  243.             break;
  244.         default:
  245.             (void)obstack_finish(&tmp_mem);
  246.             ERROR(NON_STRING);
  247.         }
  248.     }
  249.     (void)obstack_1grow(&tmp_mem,0);
  250.     p->type=TYP_STR;
  251.     p->String=(char *)obstack_finish(&tmp_mem);
  252. }
  253.  
  254.  
  255. static void
  256. do_mid FUN1(struct value *,p)
  257. {
  258.     char *str = (p  )->String;
  259.     long from = (p+1)->Int;
  260.     long len =  (p+2)->Int;
  261.  
  262.     char    *ptr1;
  263.     int tmp;
  264.  
  265.     tmp=strlen(str);
  266.  
  267.     if(from<0 || len<0)
  268.         ERROR(OUT_OF_RANGE);
  269.     ptr1=(char *)obstack_alloc(&tmp_mem,len+1);
  270.     if(from>=tmp || len==0)
  271.         ptr1[0]='\0';
  272.     else {
  273.         strncpy(ptr1,str+from,len);
  274.         ptr1[len]='\0';
  275.     }
  276.     p->String=ptr1;
  277. }
  278.  
  279.  
  280. static void
  281. do_substr FUN1(struct value *,p)
  282. {
  283.     long off1 = (p  )->Int;
  284.     long off2 = (p+1)->Int;
  285.     char *str = (p+2)->String;
  286.  
  287.     char    *ptr1,    *ptr2;
  288.     int tmp;
  289.     char *ret;
  290.  
  291.     tmp=strlen(str);
  292.     if(off1==0 || tmp < ((off1<0) ? -off1 : off1) ||
  293.        off2==0 || tmp < ((off2<0) ? -off2 : off2))
  294.         ERROR(OUT_OF_RANGE);
  295.     ptr1=str + (off1>0 ? off1-1 : tmp+(off1));
  296.     ptr2=str + (off2>0 ? off2-1 : tmp+(off2));
  297.  
  298.     if(ptr1>ptr2)
  299.         ERROR(OUT_OF_RANGE);
  300.     tmp=(ptr2-ptr1)+1;
  301.     ret=(char *)obstack_alloc(&tmp_mem,tmp+1);
  302.     strncpy(ret,ptr1,tmp);
  303.     ret[tmp]=0;
  304.     p->String=ret;
  305.     p->type=TYP_STR;
  306. }
  307.  
  308. static void
  309. do_strstr FUN1(struct value *,p)
  310. {
  311.     char *str1    = (p  )->String;
  312.     char *strptr    = (p+1)->String;
  313.     long off    = (p+2)->Int;
  314.     char *ret;
  315.  
  316.     if(off<1 || strlen(strptr)<=off-1)
  317.         ERROR(OUT_OF_RANGE);
  318.     ret=strstr(strptr+off-1,str1);
  319.     p->Value= ret ? 1 + ret-strptr : 0;
  320.     p->type=TYP_INT;
  321. }
  322.  
  323. struct function string_funs[] = {
  324. { C_FN1,    X_A1,    "S",    do_len,        "len" },
  325. { C_FN3,    X_A3,    "SSI",  do_strstr,    "find" },
  326.  
  327. { C_FN1,    X_A1,    "S",    do_up_str,    "strupr" },
  328. { C_FN1,    X_A1,    "S",    do_dn_str,    "strlwr" },
  329. { C_FN1,    X_A1,    "S",    do_cp_str,    "strcap" },
  330. { C_FN1,    X_A1,    "S",    do_trim_str,    "trim" },
  331.  
  332. { C_FN3,    X_A3,    "IIS",  do_substr,    "substr" },
  333. { C_FN3,    X_A3,    "SII",  do_mid,        "mid" },
  334.  
  335. { C_FN2,    X_A2,    "SI",   do_repeat,    "repeat" },
  336. { C_FNN,    X_AN,    "EEEE", do_concat,    "concat" },
  337. { C_FNN,    X_AN,    "SIIS", do_edit,    "edit" },
  338. { 0,        0,    0,    0,        0 },
  339. };
  340.  
  341.